﻿' VB conversion of the code found here: http://blogs.msdn.com/b/pfxteam/archive/2013/01/13/cooperatively-pausing-async-methods.aspx

Imports System.Threading

Public Class PauseTokenSource
    Private m_paused As TaskCompletionSource(Of Boolean)

    Public Property IsPaused() As Boolean
        Get
            Return m_paused IsNot Nothing
        End Get
        Set(value As Boolean)
            If value Then
                Interlocked.CompareExchange(m_paused, New TaskCompletionSource(Of Boolean)(), Nothing)
            Else
                While True
                    Dim tcs = m_paused
                    If tcs Is Nothing Then
                        Return
                    End If
                    If Interlocked.CompareExchange(m_paused, Nothing, tcs).Equals(tcs) Then
                        tcs.SetResult(True)
                        Exit While
                    End If
                End While
            End If
        End Set
    End Property
    Friend Function WaitWhilePausedAsync() As Task
        Dim cur = m_paused
        Return If(cur IsNot Nothing, cur.Task, s_completedTask)
    End Function
    Friend Shared ReadOnly s_completedTask As Task = Task.FromResult(True)
    Public ReadOnly Property Token() As PauseToken
        Get
            Return New PauseToken(Me)
        End Get
    End Property
End Class

Public Structure PauseToken
    Private ReadOnly m_source As PauseTokenSource
    Friend Sub New(source As PauseTokenSource)
        m_source = source
    End Sub

    Public ReadOnly Property IsPaused() As Boolean
        Get
            Return m_source IsNot Nothing AndAlso m_source.IsPaused
        End Get
    End Property

    Public Function WaitWhilePausedAsync() As Task
        Return If(IsPaused, m_source.WaitWhilePausedAsync(), PauseTokenSource.s_completedTask)
    End Function
End Structure

